

package cartagows.wsframework.wssecurity.policy;

import org.apache.neethi.Policy;
import org.apache.ws.security.WSEncryptionPart;

import cartagows.wsframework.wssecurity.core.SecurityException;
import cartagows.wsframework.wssecurity.policy.model.AlgorithmSuite;
import cartagows.wsframework.wssecurity.policy.model.SecureConversationToken;
import cartagows.wsframework.wssecurity.policy.model.SupportingToken;
import cartagows.wsframework.wssecurity.policy.model.Token;
import cartagows.wsframework.wssecurity.policy.model.Trust10;
import cartagows.wsframework.wssecurity.policy.model.Wss10;
import cartagows.wsframework.wssecurity.policy.model.Wss11;

import java.util.HashMap;
import java.util.Vector;

public class PolicyData {

    /*
     * Global settings for overall security processing
     */
    private boolean symmetricBinding;   
    private boolean transportBinding;
    private boolean asymmetricBinding;
    private String layout;
    private boolean includeTimestamp;
    private boolean entireHeadersAndBodySignatures;
    private String protectionOrder;
    private boolean signatureProtection;
    private boolean tokenProtection;
    private boolean signatureConfirmation;

    /*
     * Message tokens for symmetrical binding
     */
    private Token encryptionToken;
    private Token signatureToken;
    
    /*
     * Message token for transport binding
     */
    private Token transportToken;

    /*
     * Message tokens for asymmetrical binding
     */
    private Token recipientToken; // used to encrypt data to recipient
    private Token initiatorToken; // used to sign data by initiator

    /*
     * Which parts or elements of the message to sign/encrypt with the message
     * tokens. 
     */
    private boolean signBody;
    private boolean encryptBody;
    private boolean signAttachments;
    private boolean encryptAttachments;
    private Vector signedParts = new Vector();
    private Vector signedElements = new Vector();
    private Vector encryptedParts = new Vector();
    private Vector encryptedElements = new Vector();
    private Vector requiredElements = new Vector();
    private Vector contentEncryptedElements = new Vector();
    private HashMap declaredNamespaces = new HashMap();

    /*
     * Holds the supporting tokens elements
     */
    private SupportingToken supportingTokens;
    private SupportingToken signedSupportingTokens;
    private SupportingToken endorsingSupportingTokens;
    private SupportingToken signedEndorsingSupportingTokens;  
    private SupportingToken encryptedSupportingTokens;
    private SupportingToken signedEncryptedSupportingTokens;
    private SupportingToken endorsingEncryptedSupportingTokens;
    private SupportingToken signedEndorsingEncryptedSupportingTokens;   
    private AlgorithmSuite algorithmSuite;
      
    private Trust10 trust10;
    
    private HashMap supportingTokensIdMap;
    private HashMap signedSupportingTokensIdMap;
    private HashMap endorsingSupportingTokensIdMap;
    private HashMap signedEndorsingSupportingTokensIdMap;
    
    private Wss10 wss10;
    private Wss11 wss11;
    
    private Policy issuerPolicy;
    

    public boolean isSymmetricBinding() {
        return symmetricBinding;
    }

    public void setSymmetricBinding(boolean symmetricBinding) {
        this.symmetricBinding = symmetricBinding;
    }
    
    public boolean isAsymmetricBinding() {
        return asymmetricBinding;
    }

    public void setAsymmetricBinding(boolean asymmetricBinding) {
        this.asymmetricBinding = asymmetricBinding;
    }

    public boolean isEntireHeadersAndBodySignatures() {
        return entireHeadersAndBodySignatures;
    }

    public void setEntireHeadersAndBodySignatures(
            boolean entireHeaderAndBodySignatures) {
        this.entireHeadersAndBodySignatures = entireHeaderAndBodySignatures;
    }

    public boolean isIncludeTimestamp() {
        return includeTimestamp;
    }

    public void setIncludeTimestamp(boolean includeTimestamp) {
        this.includeTimestamp = includeTimestamp;
    }

    public String getLayout() {
        return layout;
    }

    public void setLayout(String layout) {
        this.layout = layout;
    }

    public String getProtectionOrder() {
        return protectionOrder;
    }
    
    public void setProtectionOrder(String protectionOrder) {
        this.protectionOrder = protectionOrder;
    }

    public boolean isSignatureProtection() {
        return signatureProtection;
    }

    public void setSignatureProtection(boolean signatureProtection) {
        this.signatureProtection = signatureProtection;
    }

    public boolean isTokenProtection() {
        return tokenProtection;
    }

    public void setTokenProtection(boolean tokenProtection) {
        this.tokenProtection = tokenProtection;
    }

    public boolean isSignatureConfirmation() {
        return signatureConfirmation;
    }

    public void setSignatureConfirmation(boolean signatureConfirmation) {
        this.signatureConfirmation = signatureConfirmation;
    }

    public Vector getEncryptedElements() {
        return encryptedElements;
    }

    public void setEncryptedElements(String encElement) {

        encryptedElements.add(encElement);
    }
 
    public Vector getRequiredElements() {
        return requiredElements;
    }

    public void setRequiredElements(String reqElement) {
        requiredElements.add(reqElement);
    }

    public Vector getContentEncryptedElements() {
        return contentEncryptedElements;
    }

    public void setContentEncryptedElements(String encElement) {

        contentEncryptedElements.add(encElement);
    }

    public Vector getEncryptedParts() {
        return encryptedParts;
    }

    public void setEncryptedParts(String namespace, String element) {
        WSEncryptionPart wep = new WSEncryptionPart(element, namespace,
                "Element");
        encryptedParts.add(wep);
    }
    
    public void setEncryptedParts(String namespace, String element, 
    		                                       String modifier) {
        WSEncryptionPart wep = new WSEncryptionPart(element, namespace,
                modifier);
        encryptedParts.add(wep);
    }

    public boolean isEncryptBody() {
        return encryptBody;
    }

    public void setEncryptBody(boolean encryptBody) {
        this.encryptBody = encryptBody;
    }

    public boolean isSignBody() {
        return signBody;
    }

    public void setSignBody(boolean signBody) {
        this.signBody = signBody;
    }

    public boolean isSignAttachments() {
        return signAttachments;
    }

    public void setSignAttachments(boolean signAttachments) {
        this.signAttachments = signAttachments;
    }

    public boolean isEncryptAttachments() {
        return encryptAttachments;
    }

    public void setEncryptAttachments(boolean encryptAttachments) {
        this.encryptAttachments = encryptAttachments;
    }

    public Vector getSignedElements() {
        return signedElements;
    }

    public void setSignedElements(String sigElement) {

        signedElements.add(sigElement);
    }

    public Vector getSignedParts() {
        return signedParts;
    }
    
    public HashMap getDeclaredNamespaces() {
        return declaredNamespaces;
    }
    
    public void addDeclaredNamespaces(HashMap namespaces) {
        declaredNamespaces.putAll(namespaces);
    }

    public void addSignedPart(String namespace, String element) {

        WSEncryptionPart wep = new WSEncryptionPart(element, namespace,
                "Content");
        signedParts.add(wep);
    }

    public void addSignedPart(WSEncryptionPart part) {
        signedParts.add(part);
    }
    
    public void setSignedParts(Vector signedParts) {
        this.signedParts = signedParts;
    }
    
    public void setSupportingTokens(SupportingToken suppTokens)
            throws WSSPolicyException {

        int tokenType = suppTokens.getTokenType();
        if (tokenType == SPConstants.SUPPORTING_TOKEN_SUPPORTING) {
            supportingTokens = suppTokens;
        } else if (tokenType == SPConstants.SUPPORTING_TOKEN_SIGNED) {
            signedSupportingTokens = suppTokens;
        } else if (tokenType == SPConstants.SUPPORTING_TOKEN_ENDORSING) {
            endorsingSupportingTokens = suppTokens;
        } else if (tokenType == SPConstants.SUPPORTING_TOKEN_SIGNED_ENDORSING) {
            signedEndorsingSupportingTokens = suppTokens;
        } else if (tokenType == SPConstants.SUPPORTING_TOKEN_ENCRYPTED) {
            encryptedSupportingTokens = suppTokens;
        } else if (tokenType == SPConstants.SUPPORTING_TOKEN_SIGNED_ENCRYPTED) {
            signedEncryptedSupportingTokens = suppTokens;
        } else if (tokenType == SPConstants.SUPPORTING_TOKEN_ENDORSING_ENCRYPTED) {
            endorsingEncryptedSupportingTokens = suppTokens;
        } else if (tokenType == SPConstants.SUPPORTING_TOKEN_SIGNED_ENDORSING_ENCRYPTED) {
            signedEndorsingEncryptedSupportingTokens = suppTokens;
        }
    }

    public Token getEncryptionToken() {
        return encryptionToken;
    }

    public void setEncryptionToken(Token encryptionToken) {
        this.encryptionToken = encryptionToken;
        this.extractIssuerPolicy(encryptionToken);
    }

    public Token getInitiatorToken() {
        return initiatorToken;
    }

    public void setInitiatorToken(Token initiatorToken) {
        this.initiatorToken = initiatorToken;
    }

    public Token getTransportToken() {
        return transportToken;
    }

    public void setTransportToken(Token transportToken) {
        this.transportToken = transportToken;
    }

    public Token getRecipientToken() {
        return recipientToken;
    }

    public void setRecipientToken(Token recipientToken) {
        this.recipientToken = recipientToken;
    }
    
    public void setProtectionToken(Token protectionToken) {
        this.setEncryptionToken(protectionToken);
        this.setSignatureToken(protectionToken);
        this.extractIssuerPolicy(protectionToken);
    }

    public Token getSignatureToken() {
        return signatureToken;
    }

    public void setSignatureToken(Token signatureToken) {
        this.signatureToken = signatureToken;
        this.extractIssuerPolicy(signatureToken);
    }

    public SupportingToken getSignedEndorsingSupportingTokens() {
        return signedEndorsingSupportingTokens;
    }

    public void setSignedEndorsingSupportingTokens(
            SupportingToken signedEndorsingSupportingTokens) {
        this.signedEndorsingSupportingTokens = signedEndorsingSupportingTokens;
    }
   
    public SupportingToken getSignedEndorsingEncryptedSupportingTokens() {
        return signedEndorsingEncryptedSupportingTokens;
    }

    public void setSignedEndorsingEncryptedSupportingTokens(
            SupportingToken signedEndorsingEncryptedSupportingTokens) {
        this.signedEndorsingEncryptedSupportingTokens = signedEndorsingEncryptedSupportingTokens;
    }

    public SupportingToken getSignedSupportingTokens() {
        return signedSupportingTokens;
    }

    public void setSignedSupportingTokens(SupportingToken signedSupportingTokens) {
        this.signedSupportingTokens = signedSupportingTokens;
    }
    
    public SupportingToken getSignedEncryptedSupportingTokens() {
        return signedEncryptedSupportingTokens;
    }

    public void setSignedEncryptedSupportingTokens(SupportingToken signedEncryptedSupportingTokens) {
        this.signedEncryptedSupportingTokens = signedEncryptedSupportingTokens;
    }

    public SupportingToken getSupportingTokens() {
        return supportingTokens;
    }

    public void setEncryptedSupportingTokens(SupportingToken encryptedSupportingTokens) {
        this.encryptedSupportingTokens = encryptedSupportingTokens;
    }
    
    public SupportingToken getEncryptedSupportingTokens() {
        return encryptedSupportingTokens;
    }

    public void setEndorsingSupportingTokens(SupportingToken endorsingSupportingTokens) {
        this.endorsingSupportingTokens = endorsingSupportingTokens;
    }

    public SupportingToken getEndorsingSupportingTokens() {
        return endorsingSupportingTokens;
    }

    public void setEndorsingEncryptedSupportingTokens(SupportingToken endorsingEncryptedSupportingTokens) {
        this.endorsingEncryptedSupportingTokens = endorsingEncryptedSupportingTokens;
    }

    public SupportingToken getEndorsingEncryptedSupportingTokens() {
        return endorsingEncryptedSupportingTokens;
    }

    public AlgorithmSuite getAlgorithmSuite() {
        return algorithmSuite;
    }

    public void setAlgorithmSuite(AlgorithmSuite algorithmSuite) {
        this.algorithmSuite = algorithmSuite;
    }

    public Trust10 getTrust10() {
        return trust10;
    }

    public void setTrust10(Trust10 trust10) {
        this.trust10 = trust10;
    }

    public boolean isTransportBinding() {
        return transportBinding;
    }

    public void setTransportBinding(boolean transportBinding) {
        this.transportBinding = transportBinding;
    }

    public void setSupporttingtokenId(Token token, String id, int type) throws SecurityException {
        
        HashMap tokenMap = null;
        switch (type) {
        case SPConstants.SUPPORTING_TOKEN_SUPPORTING:
            if(this.supportingTokensIdMap == null) {
                this.supportingTokensIdMap = new HashMap();
            }
            tokenMap = this.supportingTokensIdMap;
            break;

        case SPConstants.SUPPORTING_TOKEN_SIGNED:
            if(this.signedSupportingTokensIdMap == null) {
                this.signedSupportingTokensIdMap = new HashMap();
            }
            tokenMap = this.signedSupportingTokensIdMap;
            break;
            
        case SPConstants.SUPPORTING_TOKEN_ENDORSING:
            if(this.endorsingSupportingTokensIdMap == null) {
                this.endorsingSupportingTokensIdMap = new HashMap();
            }
            tokenMap = this.endorsingSupportingTokensIdMap;
            break;
            
        case SPConstants.SUPPORTING_TOKEN_SIGNED_ENDORSING:
            if(this.signedEndorsingSupportingTokensIdMap == null) {
                this.signedEndorsingSupportingTokensIdMap = new HashMap();
            }
            tokenMap = this.signedEndorsingSupportingTokensIdMap;
            break;
            
        default:
            throw new SecurityException("invalidSupportingVersionType");
        }
        
        tokenMap.put(token, id);
    }
    
    public String getSupportingTokenID(Token token, int type)
            throws SecurityException {
        switch (type) {
        case SPConstants.SUPPORTING_TOKEN_SUPPORTING:
            if(this.supportingTokensIdMap != null) {
                return (String)this.supportingTokensIdMap.get(token);
            }
            return null;

        case SPConstants.SUPPORTING_TOKEN_SIGNED:
            if(this.signedSupportingTokensIdMap != null) {
                return (String)this.signedSupportingTokensIdMap.get(token);
            }
            return null;
            
        case SPConstants.SUPPORTING_TOKEN_ENDORSING:
            if(this.endorsingSupportingTokensIdMap != null) {
                return (String)this.endorsingSupportingTokensIdMap.get(token);
            }
            return null;
            
        case SPConstants.SUPPORTING_TOKEN_SIGNED_ENDORSING:
            if(this.signedEndorsingSupportingTokensIdMap == null) {
                this.signedEndorsingSupportingTokensIdMap = new HashMap();
            }
            return null;

        default:
            throw new SecurityException("invalidSupportingVersionType");
        }
    }

    public Wss10 getWss10() {
        return wss10;
    }

    public void setWss10(Wss10 wss10) {
        this.wss10 = wss10;
    }

    public Wss11 getWss11() {
        return wss11;
    }

    public void setWss11(Wss11 wss11) {
        this.wss11 = wss11;
    }
    
    private void extractIssuerPolicy(Token token) {
        if(token instanceof SecureConversationToken && this.issuerPolicy == null) {
            this.issuerPolicy = ((SecureConversationToken)token).getBootstrapPolicy();
        }
    }

    public Policy getIssuerPolicy() {
        return issuerPolicy;
    }
    
}
